package com.laozhao.wintersystem;

import java.awt.Image;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.sql.DataSource;
import javax.swing.Icon;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class WinterSystemApplication {
	
	/**
	 * to load winter system config file.
	 * path can a XML file or any files gap by ',' ,and it also could be a folder 
	 * @param path
	 * @throws ParserConfigurationException 
	 * @throws IOException 
	 * @throws SAXException 
	 */
	public static void loadConfig(String... xmlPaths){
		try {
			List<Element> elements = new ArrayList<Element>();
			for (String xmlPath : xmlPaths) {
				DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
				DocumentBuilder db = dbf.newDocumentBuilder();
				Document doc = db.parse(new File((WSTools.getSystemRootPath()+xmlPath)));
//				Document doc = db.parse(xmlFile);
				elements.add(doc.getDocumentElement());
			}

			loadSystem(elements);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	public static void loadSystem(List<Element> elements){
		if (elements != null) {	
//			Node node;
//			try {
				for (Element element : elements) {
					NodeList nodes = element.getChildNodes();
					for (int i = 0; i < nodes.getLength(); i++) {
						org.w3c.dom.Node child = nodes.item(i);
						if (child.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) {
							if (child.getNodeName().equalsIgnoreCase(System.ATTRIBUTE_NODE_NAME)) {
								System system = createNode(System.class, child);
//								try {
									system.load(child);
									system.star();
//								} catch (InstantiationException e) {
//									// TODO Auto-generated catch block
//									e.printStackTrace();
//								} catch (IllegalAccessException e) {
//									// TODO Auto-generated catch block
//									e.printStackTrace();
//								} catch (ClassNotFoundException e) {
//									// TODO Auto-generated catch block
//									e.printStackTrace();
//								} catch (ParserConfigurationException e) {
//									// TODO Auto-generated catch block
//									e.printStackTrace();
//								} catch (SAXException e) {
//									// TODO Auto-generated catch block
//									e.printStackTrace();
//								} catch (IOException e) {
//									// TODO Auto-generated catch block
//									e.printStackTrace();
//								}
							}
						}
					}
				}
//			}
		}
	}
	
	public static WSystemModel loadSystemModel(List<Element> elements){
		if (elements != null) {	
			Node node;
			try {
				for (Element element : elements) {
					// load system
					node = element.getAttributeNode(System.ATTRIBUTE_NODE_NAME);
					System system = createNode(System.class,node);
					system.setSkin(WSTools.getStringAttribute(node, System.ATTRIBUTE_SYSTEM_SKIN));
					// load system children
					NodeList nodes = node.getChildNodes();
					for (int i = 0; i < nodes.getLength(); i++) {
						org.w3c.dom.Node child = nodes.item(i);
						if (child.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) {
							if (child.getNodeName().equalsIgnoreCase(Splash.ATTRIBUTE_NODE_NAME)) {
								// load splash
								Splash splash = createNode(Splash.class,child);					
								system.setSplash(splash);								
							}else if (child.getNodeName().equalsIgnoreCase(Property.ATTRIBUTE_NODE_NAME)) {
								// load property
								Property property = createProperty(Property.class,child);
								system.setProperty(property);
							}else if (child.getNodeName().equalsIgnoreCase(Property.ATTRIBUTE_NODE_NAME)) {
								// load dataSource
//								DataSource dataSource = createDateSource(DataSource.class,child);
//								system.setDataSource(dataSource);
							}else if (child.getNodeName().equalsIgnoreCase(Frame.ATTRIBUTE_NODE_NAME)) {
								// load frame
								Frame frame = createNode(Frame.class,child);
								system.setFrame(frame);
//							}else if (child.getNodeName().equalsIgnoreCase(Property.ATTRIBUTE_NODE_NAME)) {
//								// load part
//								Property property = createNode(Property.class,child);
//								system.setProperty(property);
//							}else if (child.getNodeName().equalsIgnoreCase(Property.ATTRIBUTE_NODE_NAME)) {
//								// load tray
//								Property property = createNode(Property.class,child);
//								system.setProperty(property);
							}
						}
					}

				}
			} catch (Exception e) {
				
			}
		}
		
		return null;
	}
	
	@SuppressWarnings("unchecked")
	private static <T extends BaseNode> T createNode(Class<T> clazz , Node node) {
		
		T base = null;
		if (node != null) {
			try {
				base = (T) Class.forName(WSTools.getStringAttribute(node,BaseNode.ATTRIBUTE_CLASS)).newInstance();
				base.setId(WSTools.getStringAttribute(node, BaseNode.ATTRIBUTE_ID));
				base.setName(WSTools.getStringAttribute(node, BaseNode.ATTRIBUTE_NAME));
				base.setIcon(WSTools.getStringAttribute(node, BaseNode.ATTRIBUTE_ICON));
				base.setDescription(WSTools.getStringAttribute(node, BaseNode.ATTRIBUTE_DESCRIPTION));
			} catch (InstantiationException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (ClassNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return base;
	}

	private static <T extends Property> T createProperty(Class<T> clazz , Node node) {
		
		T base = null;
		if (node != null) {
			try {
				base = (T) Class.forName(WSTools.getStringAttribute(node,BaseNode.ATTRIBUTE_CLASS)).newInstance();
				base.setName(WSTools.getStringAttribute(node, Property.ATTRIBUTE_PROPERTY_NAME));
				base.setValue(WSTools.getStringAttribute(node, Property.ATTRIBUTE_PROPERTY_VALUE));
				// load children
				NodeList nodes = node.getChildNodes();
				for (int i = 0; i < nodes.getLength(); i++) {
					org.w3c.dom.Node child = nodes.item(i);
					if (child.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) {
						// load list
						if (child.getNodeName().equalsIgnoreCase(Property.ELEMENT_PROPERTY_LIST)) {
							// load list value
							List<String> list = new ArrayList<String>();
							NodeList values = child.getChildNodes();
							for (int j = 0; j < values.getLength(); j++) {
								org.w3c.dom.Node value = values.item(i);
								if (value.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) {
									// load list
									if (value.getNodeName().equalsIgnoreCase(Property.ELEMENT_LIST_VALUE)) {
										list.add(value.getNodeValue());
									}
								}
							}
							base.setList(list);
						}else if (child.getNodeName().equalsIgnoreCase(Property.ELEMENT_PROPERTY_PROPS)) {
							// laod map
							// load map value
							Map<String,String> map = new HashMap<String, String>();
							NodeList mapNodes = child.getChildNodes();
							for (int j = 0; j < mapNodes.getLength(); j++) {
								org.w3c.dom.Node mapNode = mapNodes.item(i);
								if (mapNode.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) {
									// load list
									if (mapNode.getNodeName().equalsIgnoreCase(Property.ELEMENT_PROPS_PROP)) {
										map.put( WSTools.getStringAttribute(mapNode, Property.ATTRIBUTE_PROP_KEY), mapNode.getNodeValue());
									}
								}
							}
							base.setProps( map);
						}
					}
				}
			} catch (InstantiationException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (ClassNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return base;
	}
}
